package com.globebill.mpos.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Process;
import android.content.Context;
import android.util.Log;

/**
 * apk安全性校验
 * @author luch
 */

public class ApkVerifyWith {

	// crc校验  判断完整性
	public static void apkVerifyWithCRC(Context context, String orginalCRC) {
		String apkPath = context.getPackageCodePath(); // 获取Apk包存储路径
		try {
			ZipFile zipFile = new ZipFile(apkPath);
			ZipEntry dexEntry = zipFile.getEntry("classes.dex"); // 读取ZIP包中的classes.dex文件
			String dexCRC = String.valueOf(dexEntry.getCrc()); // 得到classes.dex文件的CRC值
			if (!dexCRC.equals(orginalCRC)) { // 将得到的CRC值与原始的CRC值进行比较校验
				Process.killProcess(Process.myPid()); // 验证失败则退出程序
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// crc校验  获取crc值传入后台
	public static String apkVerifyWithCRC(Context context) {
		String apkPath = context.getPackageCodePath(); // 获取Apk包存储路径
		try {
			ZipFile zipFile = new ZipFile(apkPath);
			ZipEntry dexEntry = zipFile.getEntry("classes.dex"); // 读取ZIP包中的classes.dex文件
			String dexCRC = String.valueOf(dexEntry.getCrc()); // 得到classes.dex文件的CRC值
			return dexCRC;
		} catch (IOException e) {
			e.printStackTrace();
			return "";
		}

	}

	// apk-MD5值   传入后台
	public static String apkVerifyWithMD5(Context context) {
		String apkPath = context.getPackageCodePath(); // 获取Apk包存储路径
		try {
			MessageDigest dexDigest = MessageDigest.getInstance("MD5");
			byte[] bytes = new byte[1024];
			int byteCount;
			FileInputStream fis = new FileInputStream(new File(apkPath)); // 读取apk文件
			while ((byteCount = fis.read(bytes)) != -1) {
				dexDigest.update(bytes, 0, byteCount);
			}
			BigInteger bigInteger = new BigInteger(1, dexDigest.digest()); // 计算apk文件的哈希值
			String sha = bigInteger.toString(16);
			fis.close();
			return sha;
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}


	// apk-MD5值   判断完整性
	public static void apkVerifyWithMD5(Context context, String orginalMD5) {
		String apkPath = context.getPackageCodePath(); // 获取Apk包存储路径
		try {
			MessageDigest dexDigest = MessageDigest.getInstance("MD5");
			byte[] bytes = new byte[1024];
			int byteCount;
			FileInputStream fis = new FileInputStream(new File(apkPath)); // 读取apk文件
			while ((byteCount = fis.read(bytes)) != -1) {
				dexDigest.update(bytes, 0, byteCount);
			}
			BigInteger bigInteger = new BigInteger(1, dexDigest.digest()); // 计算apk文件的哈希值
			String sha = bigInteger.toString(16);
			fis.close();
			if (!sha.equals(orginalMD5)) { // 将得到的哈希值与原始的哈希值进行比较校验
				Process.killProcess(Process.myPid()); // 验证失败则退出程序
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	// sha-1  判断校验
	public static void apkVerifyWithSHA(Context context, String orginalSHA) {
		String apkPath = context.getPackageCodePath(); // 获取Apk包存储路径
		try {
			MessageDigest dexDigest = MessageDigest.getInstance("SHA-1");
			byte[] bytes = new byte[1024];
			int byteCount;
			FileInputStream fis = new FileInputStream(new File(apkPath)); // 读取apk文件
			while ((byteCount = fis.read(bytes)) != -1) {
				dexDigest.update(bytes, 0, byteCount);
			}
			BigInteger bigInteger = new BigInteger(1, dexDigest.digest()); // 计算apk文件的哈希值
			String sha = bigInteger.toString(16);
			fis.close();
			if (!sha.equals(orginalSHA)) { // 将得到的哈希值与原始的哈希值进行比较校验
				Process.killProcess(Process.myPid()); // 验证失败则退出程序
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// sha-1  传入后台
	public static String apkVerifyWithSHA(Context context) {
		String apkPath = context.getPackageCodePath(); // 获取Apk包存储路径
		try {
			MessageDigest dexDigest = MessageDigest.getInstance("SHA-1");
			byte[] bytes = new byte[1024];
			int byteCount;
			FileInputStream fis = new FileInputStream(new File(apkPath)); // 读取apk文件
			while ((byteCount = fis.read(bytes)) != -1) {
				dexDigest.update(bytes, 0, byteCount);
			}
			BigInteger bigInteger = new BigInteger(1, dexDigest.digest()); // 计算apk文件的哈希值
			String sha = bigInteger.toString(16);
			fis.close();
			return sha;
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}

	/**
	 * 获取签名证书
	 * 校验
	 **/
	public static String getSign(Context ctx) {
		try {
			PackageInfo packageInfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(),
					PackageManager.GET_SIGNATURES);
			Signature[] signs = packageInfo.signatures;
			Signature sign = signs[0];
			MessageDigest md1 = MessageDigest.getInstance("MD5");
			md1.update(sign.toByteArray());
			byte[] digest = md1.digest();
			String res = toHexString(digest);
			MessageDigest md2 = MessageDigest.getInstance("SHA1");
			md2.update(sign.toByteArray());
			byte[] digest2 = md2.digest();
			String res2 = toHexString(digest2);
			return res2;
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}
	private static String toHexString(byte[] block) {
		StringBuffer buf = new StringBuffer();
		int len = block.length;
		for (int i = 0; i < len; i++) {
			byte2hex(block[i], buf);
			if (i < len - 1) {
				buf.append(":");
			}
		}
		return buf.toString();
	}
	private static void byte2hex(byte b, StringBuffer buf) {
		char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
		int high = ((b & 0xf0) >> 4);
		int low = (b & 0x0f);
		buf.append(hexChars[high]);
		buf.append(hexChars[low]);
	}


}
